package bb.lanxing.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import com.bes.bessdk.BesSdkConstants;
import com.bes.bessdk.utils.SPHelper;
import com.besall.allbase.bluetooth.service.Protocol.ProtocolConstants;
import com.besall.allbase.bluetooth.service.Protocol.ProtocolService;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import bb.lanxing.R;
import bb.lanxing.network.CookieJarImpl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class DownloadService extends IntentService {
    public static final String ACTION_DOWNLOAD_COMPLETED = "bb.lanxing.download_completed";
    public static final String ACTION_DOWNLOAD_FAIL = "bb.lanxing.download_fail";
    private static final String ACTION_DOWNLOAD_NOTIFY = "bb.lanxing.download_notify";
    public static final String ACTION_DOWNLOAD_PROGRESS = "bb.lanxing.download_progress";
    private static final String ACTION_DOWNLOAD_SILENTLY = "bb.lanxing.download_silently";
    public static final String EXTRA_DOWNLOAD_FAILED_CODE = "bb.lanxing.download_failed_code";
    public static final String EXTRA_DOWNLOAD_IGNORE_CACHE = "bb.lanxing.download_ignore_cache";
    public static final String EXTRA_DOWNLOAD_URL = "bb.lanxing.uri";
    public static final String EXTRA_OUTPUT_PATH = "bb.lanxing.output_path";
    public static final String EXTRA_PROGRESS = "bb.lanxing.progress";
    private static final String NOTIFY_TAG = "bb.lanxing.download";
    private static final String PUSH_CHANNEL_NAME = "PUSH_NOTIFY_NAME";
    private static final int PUSH_NOTIFICATION_ID = 1;
    private static final String TAG = "DownloadService";
    private int downloadCount;
    private OkHttpClient mClient;
    private static Context mContext;
    private static ProtocolService mProService;

    public DownloadService() {
        super(TAG);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        initClient();
        downloadCount = 0;
        Log.i(TAG,"onStart");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG,"onStartCommand");
        Log.i(TAG,"intent"+intent.getAction());
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        initClient();
        downloadCount = 0;
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String action = intent.getAction();
        String extraURL = intent.getStringExtra(EXTRA_DOWNLOAD_URL);
        String extraPath = intent.getStringExtra(EXTRA_OUTPUT_PATH);
        boolean booleanExtra = intent.getBooleanExtra(EXTRA_DOWNLOAD_IGNORE_CACHE, false);
        if (ACTION_DOWNLOAD_SILENTLY.equals(action)) {
            downloadNotify(extraURL, extraPath, false, booleanExtra);
        } else if (ACTION_DOWNLOAD_NOTIFY.equals(action)) {
            downloadNotify(extraURL, extraPath, true, booleanExtra);
        } else {
            downloadNotify(extraURL, extraPath, true, booleanExtra);
        }
    }

    public static void download(Context context, ProtocolService mService,String url, String path) {
        mProService = mService;
        download(context, url, path, true);
    }

    public static void download(Context context, String url, String path, boolean isSilently) {
        mContext = context;
        Intent intent = new Intent(isSilently ? ACTION_DOWNLOAD_NOTIFY : ACTION_DOWNLOAD_SILENTLY);
        intent.putExtra(EXTRA_DOWNLOAD_URL, url);
        intent.setPackage(context.getPackageName());
        intent.putExtra(EXTRA_OUTPUT_PATH, path);
        //if (url.contains("ELPO_GR3_1.DAT"))
        if (url.contains("f1e1G3.pgl"))
        {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(() -> Toast.makeText(mContext, R.string.dialog_downloading, Toast.LENGTH_SHORT).show());
        }
        context.startService(intent);
    }

    public static void download(Context context, String url, String path, boolean isSilently, boolean isCache) {
        mContext = context;
        Intent intent = new Intent(isSilently ? ACTION_DOWNLOAD_NOTIFY : ACTION_DOWNLOAD_SILENTLY);
        intent.putExtra(EXTRA_DOWNLOAD_URL, url);
        intent.putExtra(EXTRA_DOWNLOAD_IGNORE_CACHE, isCache);
        intent.setPackage(context.getPackageName());
        intent.putExtra(EXTRA_OUTPUT_PATH, path);
        //if (url.contains("ELPO_GR3_1.DAT"))
        if (url.contains("f1e1G3.pgl"))
        {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(new Runnable() {
                public void run() {
                    Toast.makeText(mContext, R.string.dialog_downloading, Toast.LENGTH_SHORT).show();
                }
            });
        }
        context.startService(intent);
    }

    void notifySuccess(String url, String path) {
        Intent intent = new Intent(ACTION_DOWNLOAD_COMPLETED);
        intent.putExtra(EXTRA_DOWNLOAD_URL, url);
        intent.putExtra(EXTRA_OUTPUT_PATH, path);
        intent.setPackage(getPackageName());
        sendBroadcast(intent);
        //if (url.contains("ELPO_BDS_3.DAT"))
        if (url.contains("f1e1C3.pgl"))
        {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(new Runnable() {
                public void run() {
                    Toast.makeText(mContext, R.string.toast_download_finish, Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    void notifyFail(String url, String path) {
        Intent intent = new Intent(ACTION_DOWNLOAD_FAIL);
        intent.putExtra(EXTRA_DOWNLOAD_URL, url);
        intent.putExtra(EXTRA_OUTPUT_PATH, path);
        intent.setPackage(getPackageName());
        sendBroadcast(intent);
        SPHelper.putPreference(mContext, BesSdkConstants.BES_BLE_KEY_ELPO_RUNNING_FLAG, 0);
        SPHelper.putPreference(mContext, BesSdkConstants.BES_BLE_KEY_ELPO_CMD_ID, 0);
        //if (url.contains("ELPO_GR3_1.DAT"))
        if (url.contains("f1e1G3.pgl"))
        {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(new Runnable() {
                public void run() {
                    if (mProService == null){
                        Toast.makeText(mContext, R.string.toast_download_failed, Toast.LENGTH_SHORT).show();
                    }else{
                        mProService.callBackStateChangedMessage(ProtocolConstants.SYSTEM_TRANS_ELPO_DATA_FILE,getString(R.string.toast_download_failed));
                    }
                }
            });
        }
    }

    void notifyFail(String url, String path, int errCode) {
        Intent intent = new Intent(ACTION_DOWNLOAD_FAIL);
        intent.putExtra(EXTRA_DOWNLOAD_URL, url);
        intent.putExtra(EXTRA_OUTPUT_PATH, path);
        intent.putExtra(EXTRA_DOWNLOAD_FAILED_CODE, errCode);
        intent.setPackage(getPackageName());
        sendBroadcast(intent);
        SPHelper.putPreference(mContext, BesSdkConstants.BES_BLE_KEY_ELPO_RUNNING_FLAG, 0);
        SPHelper.putPreference(mContext, BesSdkConstants.BES_BLE_KEY_ELPO_CMD_ID, 0);
        //if (url.contains("ELPO_GR3_1.DAT"))
        if (url.contains("f1e1G3.pgl"))
        {
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(new Runnable() {
                public void run() {
                    if (mProService == null){
                        Toast.makeText(mContext, R.string.toast_download_failed, Toast.LENGTH_SHORT).show();
                    }else{
                        mProService.callBackStateChangedMessage(ProtocolConstants.SYSTEM_TRANS_ELPO_DATA_FILE,getString(R.string.toast_download_failed));
                    }
                }
            });
        }
    }

    void notifyProgress(int percent, String url, String path) {
        Intent intent = new Intent(ACTION_DOWNLOAD_PROGRESS);
        intent.putExtra(EXTRA_DOWNLOAD_URL, url);
        intent.putExtra(EXTRA_OUTPUT_PATH, path);
        intent.putExtra(EXTRA_PROGRESS, percent);
        intent.setPackage(getPackageName());
        sendBroadcast(intent);
    }

    void downloadNotify(String url, String path, boolean isSilently, boolean isCache) {
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(path)) {
            return;
        }
        Request build = new Request.Builder().url(url).get().build();
        File file = new File(path);
        if (file.exists()) {
            boolean del = file.delete();
            Log.d(TAG, "The file has been delete");
        }
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        if (file.exists()) {
            Log.d(TAG, "The file has been downloaded");
            notifySuccess(url, path);
            return;
        }
        try {
            Response execute = this.mClient.newCall(build).execute();
            if (execute.isSuccessful()) {
                ResponseBody body = execute.body();
                File createTempFile = File.createTempFile("tmp", null, parentFile);
                long contentLength = body.contentLength();
                InputStream byteStream = body.byteStream();
                FileOutputStream fileOutputStream = new FileOutputStream(createTempFile);
                byte[] bArr = new byte[4096];
                float f = 0.0f;
                while (true) {
                    int read = byteStream.read(bArr);
                    if (read != -1) {
                        fileOutputStream.write(bArr, 0, read);
                        f += read;
                        int i = (int) ((f / ((float) contentLength)) * 100.0f);
                        if (!isSilently) {
                            notifyProgress(i, url, path);
                        }
                        Log.d(TAG, "progress: " + i);
                    } else {
                        fileOutputStream.close();
                        byteStream.close();
                        body.close();
                        createTempFile.renameTo(file);
                        notifySuccess(url, path);
                        return;
                    }
                }
            } else {
                Log.d(TAG, "download fail");
                notifyFail(url, path, execute.code());
            }
        } catch (IOException unused) {
            notifyFail(url, path);
        }
    }

    private String getMimeType(String str) {
        int lastIndexOf = str.lastIndexOf(".");
        String substring = lastIndexOf != -1 ? str.substring(lastIndexOf + 1) : null;
        if (substring == null) {
            return null;
        }
        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(substring);
    }

    private void initClient() {
        if (mClient != null) {
            return;
        }
        mClient = new OkHttpClient.Builder()
                .cookieJar(new CookieJarImpl())
                .connectTimeout(10L, TimeUnit.SECONDS)
                .readTimeout(10L, TimeUnit.SECONDS)
                .writeTimeout(10L, TimeUnit.SECONDS)
                .build();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mClient = null;
    }
}
